package cn.jtfadmin.base.dict.service.impl;


import cn.jtfadmin.base.dict.annotations.Dict;
import cn.jtfadmin.base.dict.annotations.DictItem;
import cn.jtfadmin.base.dict.dto.DictItemModelDTO;
import cn.jtfadmin.base.dict.dto.DictModelDTO;
import cn.jtfadmin.base.dict.service.DictConfig;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

/**
 * 枚举扫描下枚举字典配置
 *
 * @author jtf
 * @since 1.0
 */
public class EnumDictScanConfig implements DictConfig {


    private String basePacage;

    /**
     * EnumDictScanConfig
     *
     * @param basePackage 基础包 aa/bb/cc
     */
    public EnumDictScanConfig(String basePackage) {
        Objects.requireNonNull(basePackage, "基础包路径不能为空");
        this.basePacage = basePackage.trim();
    }


    public List<Class<? extends Enum>> getEnumClass(){
        String basePacage = this.basePacage;
        while (StringUtils.endsWithIgnoreCase(basePacage, "/")) {
            basePacage = basePacage.substring(0, basePacage.length() - 1);
        }
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + basePacage + "/**/*.class";
        Resource[] resources;
        try {
            resources = resolver.getResources(packageSearchPath);
        } catch (IOException e) {
            return Collections.emptyList();
        }
        CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();


        Set<Class<? extends Enum>> dictEnumClassSet = new HashSet<>();

        for (Resource resource : resources) {

            try {
                MetadataReader metadataReader = factory.getMetadataReader(resource);
                String className = metadataReader.getClassMetadata().getClassName();
                Class clazz = Class.forName(className);
                if (clazz.isEnum()) {
                    dictEnumClassSet.add(clazz);
                }
            } catch (Throwable ex) {
                //
            }
        }
        return new ArrayList(dictEnumClassSet);
    }
    @Override
    public List<DictModelDTO> getInitDict() {
        Set<Class<? extends Enum>> dictEnumClassSet = new HashSet<>(getEnumClass());
        List<DictModelDTO> list = new ArrayList<>();
        dictEnumClassSet.forEach(enumClass -> {
            Dict dictAnnotation = enumClass.getAnnotation(Dict.class);
            if(dictAnnotation == null){
                return;
            }
            String name = enumClass.getSimpleName();
            String describe = null;
            if (Objects.nonNull(dictAnnotation)) {
                describe = dictAnnotation.value();
            } else {

                describe = name;
            }
            List<DictItemModelDTO> dictItemModelDTOList = new ArrayList<>();
            for (Field field : enumClass.getFields()) {
                DictItem dictItem = field.getAnnotation(DictItem.class);

                String value = field.getName();
                String title = null;

                if (Objects.nonNull(dictItem)) {
                    title = dictItem.value();
                } else {
                    title = value;
                }
                dictItemModelDTOList.add(new DictItemModelDTO(value, title));

            }
            list.add(new DictModelDTO(name, describe, dictItemModelDTOList));

        });
        return list;
    }
}
